/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package proyecto;

/**
 *
 * @author Luis Romero
 */
import java.util.logging.Level;
import java.util.logging.Logger;
import static proyecto.Constantes.*;

public class Mem extends Thread {

    SharedMem MInt;
    WB SIG;
    EX ANT;
    CacheDatos cache;
    boolean repite;
    final Object lock;
    Nucleo N;
    Reloj reloj;

    public Mem(CacheDatos c) {
        MInt = new SharedMem();
        cache = c;
        this.setName("Mem");
        repite = true;
        lock = new Object();
    }

    public void setEtapas(WB w, EX e) {
        SIG = w;
        ANT = e;
    }

    public void setNucleo(Nucleo n){
        N=n;
    }
    
    public void setReloj(Reloj reloj){
        this.reloj = reloj;
    }

    public void parar() {
        synchronized (lock) {
            try {
               // System.out.println("Parar Mem");
                lock.wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ID.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void seguir() {
        synchronized (lock) {
           // System.out.println("Seguir Mem");
            lock.notify();
        }
    }

    public void run() {
        System.out.println("Inicio Mem");
        N.seguir();
        this.parar();
        while (repite) {
            //N.seguir();
            //this.parar();
            System.out.println("MEM: "+MInt.getReg(INST)+MInt.getReg(REGF1)+MInt.getReg(REGF2)+MInt.getReg(REGD));
            SIG.MInt.setReg(INST, MInt.getReg(INST));
            SIG.MInt.setReg(REGD, MInt.getReg(REGD));
            SIG.MInt.setReg(REGF1, MInt.getReg(REGF1));
            SIG.MInt.setReg(REGF2, MInt.getReg(REGF2));
            SIG.MInt.setReg(ALUOUT, MInt.getReg(ALUOUT));
            int dir;
            int etiq;
            int word;
            int pos;
            int dato;
            switch (MInt.getReg(INST)) {
                case LW:
                    dir = MInt.getReg(ALUOUT);
                    etiq = (dir/8);
                    word = (dir/4)%2;
                    pos = etiq % 4;
                    dato = cache.getDato(etiq, pos, word);
                    SIG.MInt.setReg(LMD, dato);
                    break;
                case SW:
                    dir = MInt.getReg(ALUOUT);
                    etiq = (dir/8);
                    word = (dir/4)%2;
                    pos = etiq % 4;
                    cache.setDato(MInt.getReg(REGB), etiq, pos, word);
                    break;
                case LL:
                    dir = MInt.getReg(ALUOUT);
                    etiq = (dir/8);
                    word = (dir/4)%2;
                    pos = etiq % 4;
                    dato = cache.getDato(etiq, pos, word);
                    SIG.MInt.setReg(LMD, dato);
                    break;
                case SC:
                    dir = MInt.getReg(ALUOUT);
                    etiq = (dir/8);
                    word = (dir/4)%2;
                    pos = etiq % 4;
                    cache.setDato(MInt.getReg(REGB), etiq, pos, word);
                    break;
                case FIN:
                    repite = false;
                    break;
                case INTERRUPT:
                    SIG.MInt.setReg(INST, INTERRUPT);
                    SIG.MInt.setReg(NPC, MInt.getReg(NPC));
                    repite = false;
                    break;
                default:
                    break;
            }
            reloj.cuentaHilo(3);
            reloj.seguir();
            
            SIG.seguir();
           // ANT.seguir();
            this.parar();
            ANT.seguir();
            //SIG.seguir();
            this.parar();
            if(!repite){
                SIG.seguir();
            }
        }
        //this.seguir();
        System.out.println("Murio Mem");
    }
}
